#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include <QDebug>
#include <QProcess>
#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/int32.hpp>
#include <std_msgs/msg/float32.hpp>
#include <std_msgs/msg/float64.hpp>
#include "sensor_msgs/msg/range.hpp"
#include <std_msgs/msg/float64_multi_array.hpp>

#include <cmath>

#include <QDial>
#include <QGraphicsDropShadowEffect>
#include <QGraphicsEffect>

#include <sensor_msgs/msg/image.hpp>
#include <sensor_msgs/msg/compressed_image.hpp>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
#include <QImage>


class VoltageWheelThread;
class VoltageArmThread;
class ImuDataThread;
class Camera1DataThread;
class Camera2DataThread;
class Camera3DataThread;
class WeighDataThread;
class SpeedDataThread;
class TemDataThread;




namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    std::shared_ptr<rclcpp::Node> arm_talker_node_cpp;
    rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtr vel_pub_;
    rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr flag_pub_;
    rclcpp::Publisher<std_msgs::msg::Float64>::SharedPtr setzero_pub_;

private slots:
    // void on_voltageSlider_valueChanged(int value);
    // void on_driverButton_clicked();
    // void on_wheelPushButton_clicked();
    void display_imu(double dis_r, double dis_p, double dis_y);
    void displayrt1data(float turespeed1);
    void displayrt2data(float turespeed2);
    void displayrt3data(float turespeed3);
    void displayrt4data(float turespeed4);
    void display_camera1(cv::Mat img1);
    void display_camera2(cv::Mat img1);
    void display_camera3(cv::Mat img1);
    void display_weigh1(float dis_w1);
    void display_weigh2(float dis_w2);

    void display_tem(int tem);
    void display_distance(float data);
    void display_pos(float data);
    void display_pos_2(float data);
    void display_v1(float v1);
    void display_v2(float v2);
    void display_v1_colcor(int v1_c);
    void display_v2_colcor(int v2_c);
    void display_jor_cur_colcor(int c);
    void display_cur_speed(float sp);

    void display_thick(int thick);



private:
    Ui::MainWindow *ui;
    // 线程类
    ImuDataThread * imuDataThread;
    Camera1DataThread * camera1DataThread;
    Camera2DataThread * camera2DataThread;
    Camera3DataThread * camera3DataThread;
    WeighDataThread * weighDataThread;
    SpeedDataThread * speedDataThread;
    TemDataThread * temDataThread;

    // QProcess类
    QProcess *keyboard;
    QProcess *driver;
    QProcess *wheel;


};



// IMU数据显示线程
class ImuDataThread : public QThread
{
    Q_OBJECT

public:
    explicit ImuDataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~ImuDataThread()
    {

    }
    // run方法,在setArmVoltage.cpp中实现方法
    void run();
    void imu_data_cb(const std_msgs::msg::Float64MultiArray::SharedPtr msg);
    // 创建发布节点
    std::shared_ptr<rclcpp::Node> imu_data_node_cpp;
    // 定义电发布方
    rclcpp::Subscription<std_msgs::msg::Float64MultiArray>::SharedPtr imu_data_sub;
signals:
     void imuEmitData(double r_data, double p_data, double y_data);
};

// 速度反馈线程
class SpeedDataThread : public QThread
{
    Q_OBJECT
public:
    explicit SpeedDataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~SpeedDataThread()
    {

    }
    // run方法
    void run() override;
    void speed_data1_cb(const std_msgs::msg::Int32 speedmsg);
    void speed_data2_cb(const std_msgs::msg::Int32 speedmsg);
    void speed_data3_cb(const std_msgs::msg::Int32 speedmsg);
    void speed_data4_cb(const std_msgs::msg::Int32 speedmsg);
    // 创建发布节点
    std::shared_ptr<rclcpp::Node> speed_data_node_cpp;
    // 定义订阅方
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr speed_data1_sub;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr speed_data2_sub;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr speed_data3_sub;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr speed_data4_sub;
signals:
    void speedEmitData1(float rt1_data);
    void speedEmitData2(float rt2_data);
    void speedEmitData3(float rt3_data);
    void speedEmitData4(float rt4_data);

};

// 拉力传感器显示线程
class WeighDataThread : public QThread
{
    Q_OBJECT

public:
    explicit WeighDataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~WeighDataThread()
    {

    }
    // run方法,在setArmVoltage.cpp中实现方法
    void run();
    void weigh1_data_cb(const std_msgs::msg::Int32 weigh1_msg);
    void weigh2_data_cb(const std_msgs::msg::Int32 weigh2_msg);
    // 创建节点
    std::shared_ptr<rclcpp::Node> weigh_data_node_cpp;
    // 定义
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr weigh1_sub_;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr weigh2_sub_;
signals:
    void weigh1_emit(float w1_data);
    void weigh2_emit(float w2_data);
};

// 温度及其他传感器
class TemDataThread : public QThread
{
    Q_OBJECT

public:
    explicit TemDataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~TemDataThread()
    {

    }

    void run();
    void tem_data_cb(const std_msgs::msg::Int32 tem_msg);
    void thickness_data_cb(const std_msgs::msg::Int32 thickness_msg);
    void roughness_data_cb(const std_msgs::msg::Int32 roughness_msg);
    void voltage_array_data_cb(const std_msgs::msg::Float64MultiArray voltage_array_msg);
    void wheel_status_cd(const std_msgs::msg::Int32 msg);
    void arm_status_cd(const std_msgs::msg::Int32 msg);
    void joystick_or_cruising_cb(const std_msgs::msg::Int32 msg);
    void cruising_speed_cd(const std_msgs::msg::Int32 msg);
    void range_callback(const sensor_msgs::msg::Range::SharedPtr msg);
    void degree_callback(const std_msgs::msg::Float32 degree_msg);
    void degree_callback_2(const std_msgs::msg::Float32 degree_msg);
    // 创建节点
    std::shared_ptr<rclcpp::Node> sensor_data_node_cpp;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr tem_lis;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr thickness_lis;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr roughness_lis;
    // 两个电压值订阅
    rclcpp::Subscription<std_msgs::msg::Float64MultiArray>::SharedPtr voltage_array_lis;
    // wheel状态订阅
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr wheel_status_lis;
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr arm_status_lis;
    // 遥杆或巡航
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr joystick_or_cruising_lis;
    // 巡航速度订阅
    rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr cruising_speed_lis;
    //
    rclcpp::Subscription<sensor_msgs::msg::Range>::SharedPtr distance_lis;
    //
    rclcpp::Subscription<std_msgs::msg::Float32>::SharedPtr armpos_lis;
    rclcpp::Subscription<std_msgs::msg::Float32>::SharedPtr armpos_lis_2;




signals:
    void tem_emit(int tem_data);
    void thickness_emit(int thickness_data);
    void roughness_emit(int roughness_data);
    void distance_emit(float data);
    // 推杆电压
    void wheel_voltage_emit(float wheel_voltage_data);
    // 作业臂电压
    void arm_voltage_emit(float arm_voltage_data);
    // 推杆状态
    void wheel_status_emit(int status);
    void arm_status_emit(int status);
    // 遥杆或巡航
    void joystick_or_cruising_emit(int status);
    // 巡航速度
    void cruising_speed_emit(float speed);
    // pos
    void armpos_emit(float pos);
    void armpos_emit_2(float pos);
};

// camera显示线程
class Camera1DataThread : public QThread
{
    Q_OBJECT

public:
    explicit Camera1DataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~Camera1DataThread()
    {
        qDebug()<<"线程销毁"<<Qt::endl;
    }
    void run();
    void camera1_back(const sensor_msgs::msg::CompressedImage::SharedPtr img_msg);
    cv::Mat img1;
private:
    // 创建节点
    std::shared_ptr<rclcpp::Node> camera_node_cpp;
    // 定义
    rclcpp::Subscription<sensor_msgs::msg::CompressedImage>::SharedPtr camera1_sub_;
    // 回调函数
signals:
    void image_1Emit(cv::Mat);

};

class Camera2DataThread : public QThread
{
    Q_OBJECT

public:
    explicit Camera2DataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~Camera2DataThread()
    {
        qDebug()<<"线程销毁"<<Qt::endl;
    }
    void run();
    void camera2_back(const sensor_msgs::msg::CompressedImage::SharedPtr img_msg);
    cv::Mat img2;
private:
    // 创建节点
    std::shared_ptr<rclcpp::Node> camera2_node_cpp;
    // 定义
    rclcpp::Subscription<sensor_msgs::msg::CompressedImage>::SharedPtr camera2_sub_;
    // 回调函数
signals:
    void image_2Emit(cv::Mat);
};

class Camera3DataThread : public QThread
{
    Q_OBJECT

public:
    explicit Camera3DataThread(QWidget *parent = nullptr)
    {
        Q_UNUSED(parent);
    }
    ~Camera3DataThread()
    {
        qDebug()<<"线程销毁"<<Qt::endl;
    }
    void run();
    void camera3_back(const sensor_msgs::msg::CompressedImage::SharedPtr img_msg);
    cv::Mat img3;
private:
    // 创建节点
    std::shared_ptr<rclcpp::Node> camera3_node_cpp;
    // 定义
    rclcpp::Subscription<sensor_msgs::msg::CompressedImage>::SharedPtr camera3_sub_;
    // 回调函数
signals:
    void image_3Emit(cv::Mat);
};


#endif // MAINWINDOW_H
